/*****************************************************************
Mix3D WebGL Game Engine
Copyright (c) fantasy ( fantasy.x2x@gmail.com )
Listens:
Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt
 ****************************************************************/
/**
 * @Desc    : texture
 * @Author  : fantasy(fantasy.x2x@gmail.com)
 */
//////////////////////////////////////////////////////////////////
if(typeof(Mix3D) === 'undefined')
{
  Mix3D = {};
};
(function(Mix3D){
//////////////////////////////////////////////////////////////////
//mapping mode
Mix3D.MappinpMode_UV = function(){};
Mix3D.MappingMode_CubeReflect = function(){};
Mix3D.MappingMode_CubeRefract = function(){};
Mix3D.MappingMode_SphericalReflect = function(){};
Mix3D.MappingMode_SphericalRefract = function(){};
//wrapping mode
Mix3D.WrappingMode_Repeat = 0;
Mix3D.WrappingMode_Clamp = 1;
Mix3D.WrappingMode_Mirror = 2;
//filters
Mix3D.Filter_Point =3;
Mix3D.Filter_PointMipmapPoint = 4;
Mix3D.Filter_PointMipmapLinear = 5;
Mix3D.Filter_Linear = 6;
Mix3D.Filter_LinearMipmapPoint = 7;
Mix3D.Filter_LinearMipmapLinear = 8;

//////////////////////////////////////////////////////////////////
Mix3D.Texture = function(mapping, wrapS, wrapT, magFilter, minFilter)
{
  Mix3D.Resource.call(this);
  this.mapping = mapping!==undefined ? mapping : new Mix3D.MappinpMode_UV;
  this.wrapS = wrapS!==undefined?wrapS:Mix3D.WrappingMode_Clamp;
  this.wrapT = wrapT!==undefined?wrapT:Mix3D.WrappingMode_Clamp;
  this.magFilter = magFilter!==undefined?magFilter:Mix3D.Filter_Linear;
  this.minFilter = minFilter!==undefined?minFilter:Mix3D.Filter_LinearMipmapLinear;
  this.offset = new Mix3D.Vector2(0,0);
  this.repeat = new Mix3D.Vector2(1,1);
  this.isGenerateMipmaps = true;
  this.isPremultiplyAlpha = false;
	this.isNeedsUpdate = false;
};

Mix3D.protoCopy(Mix3D.Resource, Mix3D.Texture);
Mix3D.Texture.prototype.constructor = Mix3D.Texture;
Mix3D.Texture.prototype.className = 'Texture';

Mix3D.Texture.prototype.imageRequestBack = function( image )
{
  this.image = image;
  if(this.image)
  {
    this.isNeedsUpdate = true;
    this.isCube = this.image.constructor === Array;
  }
};

Mix3D.Texture.prototype.fromImage = function(imageName)
{
  if(this.imageResName !== imageName)
  {
    this.imageResName = imageName;
    Mix3D.Image.request(imageName, Mix3D.bind(this, this.imageRequestBack));
	}
	return this;
};


Mix3D.Texture.prototype.UV_MapMode = function() { this.mapping = new Mix3D.MappinpMode_UV; return this; };
Mix3D.Texture.prototype.CubeRL_MapMode = function() { this.mapping = new Mix3D.MappingMode_CubeReflect; return this; };
Mix3D.Texture.prototype.CubeRR_MapMode = function() { this.mapping = new Mix3D.MappingMode_CubeRefract; return this; };
Mix3D.Texture.prototype.SphereRL_MapMode = function() { this.mapping = new Mix3D.MappingMode_SphericalReflect; return this; };
Mix3D.Texture.prototype.SphereRR_MapMode = function() { this.mapping = new Mix3D.MappingMode_SphericalRefract; return this; };
Mix3D.Texture.prototype.ClampS = function() { this.wrapS = Mix3D.WrappingMode_Clamp; return this; };
Mix3D.Texture.prototype.RepeatS = function() { this.wrapS = Mix3D.WrappingMode_Repeat; return this; };
Mix3D.Texture.prototype.MirrorS = function() { this.wrapS = Mix3D.WrappingMode_Mirror; return this; };
Mix3D.Texture.prototype.ClampT = function() { this.wrapT = Mix3D.WrappingMode_Clamp; return this; };
Mix3D.Texture.prototype.RepeatT = function() { this.wrapT = Mix3D.WrappingMode_Repeat; return this; };
Mix3D.Texture.prototype.MirrorT = function() { this.wrapT = Mix3D.WrappingMode_Mirror; return this; };
Mix3D.Texture.prototype.MagLinear = function() { this.magFilter = Mix3D.Filter_Linear; return this; };
Mix3D.Texture.prototype.MagPoint = function() { this.magFilter = Mix3D.Filter_Point; return this; };
Mix3D.Texture.prototype.MipmapPP = function() { this.minFilter = Mix3D.Filter_PointMipmapPoint; return this; };
Mix3D.Texture.prototype.MipmapPL = function() { this.minFilter = Mix3D.Filter_PointMipmapLinear; return this; };
Mix3D.Texture.prototype.MipmapLP = function() { this.minFilter = Mix3D.Filter_LinearMipmapPoint; return this; };
Mix3D.Texture.prototype.MipmapLL = function() { this.minFilter = Mix3D.Filter_LinearMipmapLinear; return this; };
Mix3D.Texture.prototype.setOffset = function( x, y ) { this.offset.set(x,y); return this; };
Mix3D.Texture.prototype.setRepeat = function( u, v ) { this.repeat.set(u,v); return this; };
Mix3D.Texture.prototype.setGenMipmaps = function(is) { this.isGenerateMipmaps = is; return this; };
Mix3D.Texture.prototype.setPreMulAlpha = function(is) { this.isPremultiplyAlpha = is; return this; };
Mix3D.Texture.prototype.NeedsUpdate = function() { this.isNeedsUpdate = true; return true; };

Mix3D.Texture.prototype.clone = function()
{
  var tex = new Mix3D.Texture(this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter);
  tex.offset.copy(this.offset);
  tex.repeat.copy(this.repeat);
  tex.imageResName = this.imageResName;
  tex.image = this.image;
  return tex;
};

Mix3D.Texture.prototype.isReady = function()
{ 
  return this.image!==undefined && this.image.isReady(); 
};

Mix3D.Texture.prototype.create = function()
{
  if(this.imageResName && !this.image)
  {
    this.image = Mix3D.Image.request(this.imageResName, Mix3D.bind(this, this.imageRequestBack));
	}
};

Mix3D.Texture.prototype.release = function()
{
};

Mix3D.Texture.prototype.load = function(stream) 
{
  var mapping = stream.read('mapping');
  if(mapping === 'UV')
  {
    this.UV_MapMode();
  }
  else if( mapping === 'CubeReflect')
  {
    this.CubeRL_MapMode();
  }
  else if( mapping === 'CubeRefract')
  {
    this.CubeRR_MapMode();
  }
  else if( mapping === 'SphericalReflect')
  {
    this.SphereRL_MapMode();
  }
  else if( mapping === 'SphericalRefract')
  {
    this.SphereRR_MapMode();
  }
  this.wrapS = stream.read('wraps');
  this.wrapT = stream.read('wrapt');
  this.magFilter = stream.read('magFilter');
  this.minFilter = stream.read('minFilter');
  this.offset.fromArray(stream.read('offset'));
  this.repeat.fromArray(stream.read('repeat'));
  this.isGenerateMipmaps = stream.read('genMipmaps');
  this.isPremultiplyAlpha = stream.read('premAlpha');
  this.imageResName = stream.read('image');

};

Mix3D.Texture.prototype.save = function(stream)
{
  stream.write('premAlpha', this.isPremultiplyAlpha);
  stream.write('image', this.image.name);
  
  var mapping = typeof this.mapping;
  if(mapping === 'Mix3D.MappinpMode_UV')
  {
    stream.write('mapping', 'UV');
  }
  else if( mapping === 'Mix3D.MappingMode_CubeReflect')
  {
    stream.write('mapping', 'CubeReflect');
  }
  else if( mapping === 'Mix3D.MappingMode_CubeRefract')
  {
    stream.write('mapping', 'CubeRefract');
  }
  else if( mapping === 'Mix3D.MappingMode_SphericalReflect')
  {
    stream.write('mapping', 'SphericalReflect');
  }
  else if( mapping === 'Mix3D.MappingMode_SphericalRefract')
  {
    stream.write('mapping', 'SphericalRefract');
  }
  stream.write('wraps', this.wrapS);
  stream.write('wrapt', this.wrapT);
  stream.write('magFilter', this.magFilter);
  stream.write('minFilter', this.minFilter);
  stream.write('offset', this.offset.toArray());
  stream.write('repeat', this.repeat.toArray());
  stream.write('genMipmaps', this.isGenerateMipmaps);
};

Mix3D.defineResourceType(Mix3D.Texture);
//////////////////////////////////////////////////////////////////
})(Mix3D);// end of function(Mix3D)